package com.tezign.intelligence.mini.dam.aifamilyconsultant.controller;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONUtil;
import com.alibaba.dashscope.common.Role;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.bean.FamilyMemberWithUserInfoBean;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.bean.ResponseBean;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.bean.UserSessionCountDTO;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.bean.UserStatusEnum;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.bean.req.*;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.bean.resp.AdminPromptResp;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.bean.resp.FamilyVO;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.bean.resp.ReportVO;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.bean.resp.UserVO;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.constant.Constant;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.constant.UserTypeEnum;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.entity.*;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.mapper.SessionMapper;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.service.*;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.util.ChatGPTUtil;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.util.ChatUtil;
import com.tezign.intelligence.mini.dam.aifamilyconsultant.util.DeepSeekUtil;
import com.volcengine.ark.runtime.model.completion.chat.ChatMessageRole;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;
import reactor.core.publisher.Mono;

import javax.validation.Valid;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;

import static com.tezign.intelligence.mini.dam.aifamilyconsultant.constant.Constant.IGNORE_SESSION_CONTENT;
import static com.tezign.intelligence.mini.dam.aifamilyconsultant.constant.Constant.SESSION_PROMPT_SUFFIX;
import static com.tezign.intelligence.mini.dam.aifamilyconsultant.constant.Constant.TOKEN_PREFIX;

/**
 * @Author ouyangkang
 * @date 2024/11/26
 */

@Api(tags = "后台管理")
@Slf4j
@CrossOrigin("*")
@RestController
@RequiredArgsConstructor
@RequestMapping(Constant.APPLICATION_NAME + "/admin")
public class AdminController {
	private final IFamilyService familyService;

	private final IUserSessionService userSessionService;

	private final ISessionService sessionService;

	private final IFamilyMemberService familyMemberService;

	private final IReportService reportService;

	private final IUserService userService;

	private final RedisTemplate<String, String> redisTemplate;

	private final SessionMapper sessionMapper;

	private final ILargeModelService largeModelService;

	public static final String REPORT_PROMPT_KEY = "report.prompt.key";
	public static final String SESSION_PROMPT_KEY = "session.prompt.key";

	private static final SimpleDateFormat SIMPLE_DATEFORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

	private static final ExecutorService executorService = Executors.newFixedThreadPool(10);

	@DeleteMapping("/family/delete/{familyId}")
	@ApiOperation(value = "删除家庭")
	public ResponseBean<Boolean> FamilyDelete(@PathVariable("familyId") Long familyId) {
		log.info("admin 删除家庭 req:{}", JSONUtil.toJsonStr(familyId));
		boolean result = familyService.removeById(familyId);
		return new ResponseBean<Boolean>().success(result);
	}

	@PostMapping("/create")
	@ApiOperation(value = "创建家庭")
	public ResponseBean<FamilyVO> create(@RequestBody @Valid AdminCreateFamilyReq req) {
		log.info("admin 创建家庭 req:{}", JSONUtil.toJsonStr(req));

		Family family = BeanUtil.copyProperties(req, Family.class);
		// 自动生成code
		String newFamilyCode = familyService.generateNewCode();
		family.setCode(newFamilyCode);
		familyService.save(family);

		FamilyVO familyVO = BeanUtil.copyProperties(family, FamilyVO.class);
		return new ResponseBean<FamilyVO>().success(familyVO);
	}

	// 修改家庭信息
	@PostMapping("/update")
	@ApiOperation(value = "修改家庭信息")
	public ResponseBean<Boolean> update(@RequestBody UpdateFamilyReq updateFamilyReq) {
		log.info("admin 修改家庭信息 family:{}", JSONUtil.toJsonStr(updateFamilyReq));
		Family family = familyService.getById(updateFamilyReq.getId());
		if (family == null) {
			return new ResponseBean<Boolean>().exception(UserStatusEnum.ERROR.addErrorMsg("家庭不存在"));
		}
		if (StringUtils.isNotBlank(updateFamilyReq.getName())) {
			family.setName(updateFamilyReq.getName());
		}
		if (updateFamilyReq.getReportTypeEnum() != null) {
			family.setReportType(updateFamilyReq.getReportTypeEnum().getType());
		}
		if (updateFamilyReq.getFocus() != null) {
			family.setFocus(updateFamilyReq.getFocus());
		}
		return new ResponseBean<Boolean>().success(familyService.updateById(family));
	}

	@PostMapping("/queryFamilyList")
	@ApiOperation(value = "获取家庭列表")
	public ResponseBean<List<FamilyVO>> queryFamilyList(@RequestBody QueryFamilyReq req) {
		LambdaQueryWrapper<Family> query =
				Wrappers.<Family>lambdaQuery()
						.eq(req.getFocus() != null, Family::getFocus, req.getFocus())
						.like(!StringUtils.isEmpty(req.getName()), Family::getName, req.getName())
						.like(!StringUtils.isEmpty(req.getCode()), Family::getCode, req.getCode())
						.ge(req.getCreateStartDate() != null, Family::getCreateTime, req.getCreateStartDate())
						.le(req.getCreateEndDate() != null, Family::getCreateTime, req.getCreateEndDate())
						.ge(req.getLastReportStartDate() != null, Family::getLastReportTime, req.getLastReportStartDate())
						.le(req.getLastReportEndDate() != null, Family::getLastReportTime, req.getLastReportEndDate())
						.orderByDesc(Family::getFocus)
						.orderByDesc(Family::getId);
		List<Family> familyList = familyService.list(query);
		if (CollectionUtils.isEmpty(familyList)) {
			return new ResponseBean<List<FamilyVO>>().success(new ArrayList<>());
		}
		List<Long> familyIdList = familyList.stream().map(Family::getId).collect(Collectors.toList());
		List<UserSession> userSessionList = userSessionService.lambdaQuery().in(UserSession::getFamilyId, familyIdList).list();
		if (CollectionUtils.isEmpty(userSessionList)) {
			return new ResponseBean<List<FamilyVO>>().success(familyList.stream().map(x -> BeanUtil.copyProperties(x, FamilyVO.class)).collect(Collectors.toList()));
		}
		Map<Long, List<Long>> famalIdUserSessionIdMap = userSessionList.stream().collect(Collectors.toMap(UserSession::getFamilyId, y -> Lists.newArrayList(y.getId()), (k1, k2) -> {
			k1.addAll(k2);
			return k1;
		}));
		
		Map<Long, Long> userSessionIdFamilyIdMap = userSessionList.stream().collect(Collectors.toMap(UserSession::getId, UserSession::getFamilyId));

		List<Long> sessionIdList = Lists.newArrayList();
		famalIdUserSessionIdMap.forEach((k, v) -> sessionIdList.addAll(v));
		List<UserSessionCountDTO> sessionCounts = sessionMapper.getSessionCounts(sessionIdList, IGNORE_SESSION_CONTENT);
		Map<Long, Long> userSessionCount = sessionCounts.stream().collect(Collectors.toMap(UserSessionCountDTO::getUserSessionId, UserSessionCountDTO::getCount, (k1, k2) -> k1));

		// 计算昨日的每个家庭的会话记录数，昨天0点到24点
		LocalDateTime yesterday = LocalDateTime.now().minusDays(1);
		LocalDateTime startTime = yesterday.withHour(0).withMinute(0).withSecond(0).withNano(0);
		LocalDateTime endTime = yesterday.withHour(23).withMinute(59).withSecond(59).withNano(999999999);
		List<Session> yesterdaySessionList = sessionService.lambdaQuery()
		.between(Session::getCreateTime, startTime, endTime)
		.notIn(Session::getContent, IGNORE_SESSION_CONTENT)
		.list();
		Map<Long, Long> familyIdYesterdaySessionCountMap = Maps.newHashMap();
		if (CollectionUtils.isNotEmpty(yesterdaySessionList)) {
			for (Session session : yesterdaySessionList) {
				Long familyId = userSessionIdFamilyIdMap.get(session.getUserSessionId());
				if (familyId != null) {
					familyIdYesterdaySessionCountMap.put(familyId, familyIdYesterdaySessionCountMap.getOrDefault(familyId, 0L) + 1);
				}
			}
		}

		List<FamilyVO> res = familyList.stream().map(x -> {
			FamilyVO familyVO = BeanUtil.copyProperties(x, FamilyVO.class);
			Long id = familyVO.getId();
			List<Long> usessionList = famalIdUserSessionIdMap.get(id);
			if (!CollectionUtils.isEmpty(usessionList)) {
				familyVO.setSessionCount(0L);
				for (Long userSessionId : usessionList) {
					Long count = userSessionCount.get(userSessionId);
					if (count != null) {
						familyVO.setSessionCount(familyVO.getSessionCount() + count);
					}
				}
			}

			Long yesterdaySessionCount = familyIdYesterdaySessionCountMap.get(id);
			if (yesterdaySessionCount != null) {
				familyVO.setYesterdaySessionCount(yesterdaySessionCount);
			}	

			return familyVO;
		}).collect(Collectors.toList());

		return new ResponseBean<List<FamilyVO>>().success(res);
	}
	// 生成会话报告 根据开始和结束时间

	@PostMapping("/generateReport")
	@ApiOperation(value = "生成会话报告")
	public ResponseBean<Boolean> generateReport(@RequestBody @Valid GenerateReportReq req) {
		log.info("admin 生成会话报告 req:{}", JSONUtil.toJsonStr(req));
		// 判断开始时间和结束时间是否正确
		String startTimeStr = req.getStartTime();
		String endTimeStr = req.getEndTime();
		Date startTime = null;
		Date endTime = null;
		try {
			startTime = SIMPLE_DATEFORMAT.parse(startTimeStr);
			endTime = SIMPLE_DATEFORMAT.parse(endTimeStr);
		} catch (ParseException e) {
			return new ResponseBean<Boolean>().exception(UserStatusEnum.ERROR.addErrorMsg("时间格式不正确"));
		}
		Long familyId = req.getFamilyId();
		if (startTime.after(endTime)) {
			return new ResponseBean<Boolean>().exception(UserStatusEnum.ERROR.addErrorMsg("开始时间不能大于结束时间"));
		}
		Family family = familyService.getById(familyId);
		if (family == null) {
			return new ResponseBean<Boolean>().exception(UserStatusEnum.ERROR.addErrorMsg("家庭不存在"));
		}

		List<UserSession> userSessions = userSessionService.lambdaQuery()
				.eq(UserSession::getFamilyId, familyId)
				.list();
		if (CollectionUtils.isEmpty(userSessions))  {
			return new ResponseBean<Boolean>().exception(UserStatusEnum.ERROR.addErrorMsg("没有符合条件的会话或对话数小于10"));
		}
		// 获取userIdList
		List<Long> userIdList = userSessions.stream().map(UserSession::getUserId).distinct().collect(Collectors.toList());


		// 转换为map key为userId value 为role
		Map<Long, List<List<Session>>> mapSession = Maps.newHashMap();
		for (UserSession userSession : userSessions) {
			Long userSessionId = userSession.getId();
//			List<Session> sessionList = sessionService.lambdaQuery().eq(Session::getUserSessionId, userSessionId).between(Session::getCreateTime, startTime, endTime)
//					.notIn(Session::getContent, IGNORE_SESSION_CONTENT)
//					.orderByAsc(Session::getId).list();
			// 20250703应付老师的要求查询所有的会话记录生成报告
			List<Session> sessionList = sessionService.lambdaQuery().eq(Session::getUserSessionId, userSessionId)
					.notIn(Session::getContent, IGNORE_SESSION_CONTENT)
					.orderByAsc(Session::getId).list();
			if (CollectionUtils.isEmpty(sessionList)) {
				continue;
			}
			Long userId = userSession.getUserId();
			List<List<Session>> sessionOrDefault = mapSession.getOrDefault(userId, Lists.newArrayList());
			sessionOrDefault.add(sessionList);
			mapSession.put(userId, sessionOrDefault);
		}
		if (CollectionUtils.isEmpty(mapSession)) {
			return new ResponseBean<Boolean>().exception(UserStatusEnum.ERROR.addErrorMsg("没有符合条件的会话"));
		}

		// 如果聊天总数 < 2，则不生成报告
		List<Session> allSessionList = mapSession.values()         // 获取所有 List<List<Session>>
		    .stream()                                             // 转为 Stream<List<List<Session>>>
		    .flatMap(listOfLists -> listOfLists.stream())         // 打平为 Stream<List<Session>>
		    .flatMap(list -> list.stream())                       // 再次打平为 Stream<Session>
		    .collect(Collectors.toList()); 
		if(allSessionList.size() < 2) {
			return new ResponseBean<Boolean>().exception(UserStatusEnum.ERROR.addErrorMsg("沟通记录少小于 2 无法生成报告"));
		}

		List<User> userList = userService.listByIds(userIdList);
		Map<Long, User> userMap = userList.stream().collect(Collectors.toMap(User::getId, y -> y, (k1, k2) -> k1));
		List<FamilyMember> members = familyMemberService.lambdaQuery().eq(FamilyMember::getFamilyId, familyId)
				.in(FamilyMember::getUserId, userIdList).list();
		Map<Long, String> memberMap = members.stream().collect(Collectors.toMap(FamilyMember::getUserId, FamilyMember::getRole));
		StringJoiner joiner = new StringJoiner("\n");
		String prompt = redisTemplate.opsForValue().get(REPORT_PROMPT_KEY);

		joiner.add("以下是家庭【" + family.getName() + "】中各个家庭成员与AI顾问的对话记录：");
		mapSession.forEach((key, value) -> {
			String role = memberMap.get(key);
			joiner.add("# 以下是 AI顾问 和" + role + "的对话：");
			int i = 1;
			for (List<Session> sessionList : value) {
				joiner.add("## 【会话" + i + "】");
				for (Session session : sessionList) {
					if (session.getRole().equals(ChatMessageRole.SYSTEM.value())) {
						continue;
					}
					if (session.getRole().equals(ChatMessageRole.ASSISTANT.value())) {
						joiner.add("AI顾问:" + session.getContent());
					}
					if (session.getRole().equals(ChatMessageRole.USER.value())) {
						joiner.add(role + "：" + session.getContent());
					}
				}
				joiner.add("");
				i++;
			}
		});
		LocalDateTime startLocalDate = startTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
		LocalDateTime endLocalDate = endTime.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();

		executorService.execute(() -> {
			try {
				log.info("admin 生成会话报告 req:{}", joiner);
				String res;
				LargeModel dbLargeModel = largeModelService.getOne(new LambdaQueryWrapper<LargeModel>().eq(LargeModel::getScope, "启用"));
				if (dbLargeModel != null){
					res = ChatGPTUtil.chatCompletion(StringUtils.isEmpty(prompt) ? req.getReportPrompt() : prompt, joiner.toString(), dbLargeModel.getModel());
				}else {
					res = ChatUtil.callWithMessage(StringUtils.isEmpty(prompt) ? req.getReportPrompt() : prompt, joiner.toString());
				}
//				String res = String.valueOf(DeepSeekUtil.chatCompletion(StringUtils.isEmpty(prompt) ? req.getReportPrompt() : prompt, joiner.toString()));
				log.info("admin 生成会话报告 res:{}", res);
				// 保存报告
				Report report = new Report();
				report.setFamilyId(familyId);
				report.setReport(res);
				Long sessionCount = 0L;
				for (List<List<Session>> value : mapSession.values()) {
					sessionCount += value.stream().mapToLong(List::size).sum();
				}
				report.setSessionCount(sessionCount);
				report.setSessionStartTime(startLocalDate);
				report.setSessionEndTime(endLocalDate);
				reportService.save(report);
				// 更新家庭信息
				family.setLastReportTime(LocalDateTime.now());
				family.setLastReportId(report.getId());
				familyService.updateById(family);
			} catch (Exception e) {
				log.error("生成报告异常", e);
			}
		});

		return new ResponseBean<Boolean>().success(true);
	}

	// 查看该家庭的所有报告信息
	@GetMapping("/queryReportList")
	@ApiOperation(value = "查看该家庭的所有报告信息")
	public ResponseBean<Page<ReportVO>> queryReportList(@RequestParam Long familyId,
														@RequestParam(required = false, defaultValue = "0", name = "page") Integer page,
														@RequestParam(required = false, defaultValue = "10", name = "size") Integer size
	) {
		Family family = familyService.getById(familyId);
		if (family == null) {
			return new ResponseBean<Page<ReportVO>>().exception(UserStatusEnum.ERROR.addErrorMsg("家庭不存在"));
		}
		Page<Report> pageInfo = new Page<>(page, size);
		Page<Report> reportPage = reportService.page(pageInfo, new LambdaQueryWrapper<Report>().eq(Report::getFamilyId, familyId).orderByDesc(Report::getId));
		List<Report> records = reportPage.getRecords();
		if (CollectionUtils.isEmpty(records)) {
			return new ResponseBean<Page<ReportVO>>().success(new Page<>());
		}
		Page<ReportVO> reportVOPage = new Page<>();
		reportVOPage.setRecords(records.stream().map(x -> {
			ReportVO reportVO = BeanUtil.copyProperties(x, ReportVO.class);
			reportVO.setFamilyVO(BeanUtil.copyProperties(family, FamilyVO.class));
			return reportVO;
		}).collect(Collectors.toList()));
		reportVOPage.setTotal(reportPage.getTotal());
		reportVOPage.setSize(reportPage.getSize());
		reportVOPage.setCurrent(reportPage.getCurrent());
		return new ResponseBean<Page<ReportVO>>().success(reportVOPage);
	}

	@GetMapping("/queryDailyRecordCount")
	@ApiOperation(value = "查看该家庭的聊天数日报表")
	public ResponseBean<List<Map<String, Object>>> queryDailyRecordCount(@RequestParam Long familyId) {
		Family family = familyService.getById(familyId);
		if (family == null) {
			return new ResponseBean<List<Map<String, Object>>>().success(new ArrayList<>());
		}
		List<UserSession> allUserSessions = userSessionService.lambdaQuery().eq(UserSession::getFamilyId, familyId).list();
		if(CollUtil.isEmpty(allUserSessions)) {
			return new ResponseBean<List<Map<String, Object>>>().success(new ArrayList<>());
		}
		List<Long> allUserSessionIds = allUserSessions.stream().map(UserSession::getId).collect(Collectors.toList());
		if(CollUtil.isEmpty(allUserSessionIds)) {
			return new ResponseBean<List<Map<String, Object>>>().success(new ArrayList<>());
		}

		QueryWrapper<Session> queryWrapper = new QueryWrapper<>();
		queryWrapper.select("DATE(create_time) AS date, COUNT(*) AS count")
				.eq("status", 0)
				.in("user_session_id", allUserSessionIds)
				.notIn("content", IGNORE_SESSION_CONTENT)
				.groupBy("DATE(create_time)")
				.orderByDesc("DATE(create_time)");

		List<Map<String, Object>> result = sessionMapper.selectMaps(queryWrapper);
		return new ResponseBean<List<Map<String, Object>>>().success(result);
	}

	@GetMapping("/queryReport")
	@ApiOperation(value = "查看该家庭的单个报告信息")
	public ResponseBean<ReportVO> queryReport(@RequestParam Long reportId) {
		Report report = reportService.getById(reportId);
		if (report == null) {
			return new ResponseBean<ReportVO>().exception(UserStatusEnum.ERROR.addErrorMsg("报告不存在"));
		}
		Long familyId = report.getFamilyId();
		Family family = familyService.getById(familyId);
		if (family == null) {
			return new ResponseBean<ReportVO>().exception(UserStatusEnum.ERROR.addErrorMsg("家庭不存在"));
		}
		ReportVO reportVO = BeanUtil.copyProperties(report, ReportVO.class);
		reportVO.setFamilyVO(BeanUtil.copyProperties(family, FamilyVO.class));
		return new ResponseBean<ReportVO>().success(reportVO);
	}

	// 获取家庭成员列表
	@GetMapping("/getFamilyMemberList/{familyId}")
	@ApiOperation(value = "获取家庭成员列表")
	public ResponseBean<List<FamilyMemberWithUserInfoBean>> getFamilyMemberList(@PathVariable("familyId") Long familyId) {
		ResponseBean<List<FamilyMemberWithUserInfoBean>> res = new ResponseBean<>();
		List<FamilyMember> members = familyMemberService.lambdaQuery().eq(FamilyMember::getFamilyId, familyId).list();
		if (CollectionUtils.isEmpty(members)) {
			return res;
		}
		List<Long> userIds = members.stream().map(FamilyMember::getUserId).collect(Collectors.toList());
		List<User> userList = userService.listByIds(userIds);
		Map<Long, User> map = userList.stream().collect(Collectors.toMap(User::getId, y -> y, (k1, k2) -> k1));
		List<FamilyMemberWithUserInfoBean> data = members.stream().map(x -> {
			FamilyMemberWithUserInfoBean familyMemberWithUserInfoBean = BeanUtil.copyProperties(x, FamilyMemberWithUserInfoBean.class);
			Long userId = x.getUserId();

			User user = map.get(userId);
			if (user != null) {
				familyMemberWithUserInfoBean.setSex(user.getSex());
				familyMemberWithUserInfoBean.setName(user.getName());
				familyMemberWithUserInfoBean.setBirthday(user.getBirthday());
			}
			return familyMemberWithUserInfoBean;
		}).collect(Collectors.toList());
		return res.success(data);
	}

	@DeleteMapping("/user/delete/{userId}")
	@ApiOperation(value = "删除用户")
	public ResponseBean<Boolean> userDelete(@PathVariable("userId") Long userId) {
		log.info("admin 删除用户 req:{}", JSONUtil.toJsonStr(userId));
		// 删除用户
		boolean result = userService.removeById(userId);
		// 删除该用户与家庭的成员关系
		familyMemberService.remove(
				Wrappers.<FamilyMember>lambdaQuery().eq(FamilyMember::getUserId, userId)
		);
		return new ResponseBean<Boolean>().success(result);
	}

	@PostMapping("/user/list")
	@ApiOperation(value = "搜索家庭用户列表")
	public ResponseBean<List<UserVO>> userList(@RequestBody QueryUserReq userReq) {
		List<User> userList = userService.list(
				new LambdaQueryWrapper<User>()
						.eq(Objects.nonNull(userReq.getActiveFamilyId()), User::getActiveFamilyId, userReq.getActiveFamilyId())
						.like(Objects.nonNull(userReq.getName()), User::getName, userReq.getName())
						.orderByDesc(User::getCreateTime)
		);

		if (CollUtil.isEmpty(userList)) {
			return new ResponseBean<List<UserVO>>().success(new ArrayList<>());
		}

		List<Long> activeFamilyIdList = userList.stream()
				.map(User::getActiveFamilyId)
				.filter(Objects::nonNull).collect(Collectors.toList());
		Map<Long, Family> familyIdObjMap = new HashMap<>();
		if (!activeFamilyIdList.isEmpty()) {
			List<Family> familyList = familyService.listByIds(activeFamilyIdList);
			familyIdObjMap.putAll(familyList.stream().collect(Collectors.toMap(Family::getId, Function.identity(), (k1, k2) -> k1)));
		}

		Map<Long, FamilyMember> userIdFamilyMemberMap = new HashMap<>();
		List<Long> userIds = userList.stream().map(User::getId).collect(Collectors.toList());
		if (!userIds.isEmpty()) {
			List<FamilyMember> familyMemberList = familyMemberService.list(
					new LambdaQueryWrapper<FamilyMember>()
							.in(FamilyMember::getUserId, userIds)
							.eq(Objects.nonNull(userReq.getActiveFamilyId()), FamilyMember::getFamilyId, userReq.getActiveFamilyId())
			);
			userIdFamilyMemberMap.putAll(familyMemberList.stream().collect(Collectors.toMap(FamilyMember::getUserId, Function.identity(), (k1, k2) -> k1)));
		}

		List<UserVO> userVoList = userList.stream().map(user -> BeanUtil.copyProperties(user, UserVO.class))
				.filter(userVo -> {
					Family activeFamily = familyIdObjMap.get(userVo.getActiveFamilyId());
					if (Objects.nonNull(activeFamily)) {
						userVo.setActiveFamilyName(activeFamily.getName());
						userVo.setActiveFamilyCode(activeFamily.getCode());
					}

					FamilyMember familyMember = userIdFamilyMemberMap.get(userVo.getId());
					if (Objects.nonNull(familyMember)) {
						userVo.setRole(familyMember.getRole());
					}

					if (StrUtil.isNotBlank(userReq.getRole()) && (Objects.isNull(familyMember) || !StrUtil.equals(userReq.getRole(), familyMember.getRole()))) {
						return false;
					}

					if (Objects.nonNull(userReq.getActiveFamilyId()) && (Objects.isNull(familyMember) || !Objects.equals(userReq.getActiveFamilyId(), familyMember.getFamilyId()))) {
						return false;
					}

					return true;
				})
				.collect(Collectors.toList());
		return new ResponseBean<List<UserVO>>().success(userVoList);
	}

	/**
	 * 用户登录
	 *
	 * @return
	 * @throws
	 * @since 2024/11/16 22:49
	 */
	@PostMapping("/user/login")
	@ApiOperation(value = "用户登录")
	public ResponseBean<UserVO> login(@RequestBody @Valid LoginReq loginReq) {
		log.info("后台用户登录");
		String password = loginReq.getPassword();
		// md5加密
		String md5Password = DigestUtils.md5DigestAsHex(password.getBytes());
		User one = userService.lambdaQuery()
				.eq(User::getUserType, UserTypeEnum.ADMIN.getValue())
				.eq(User::getName, loginReq.getName())
				.eq(User::getPassword, md5Password)
				.last("limit 1").one();
		if (one == null) {
			return new ResponseBean<UserVO>().exception(UserStatusEnum.ERROR.addErrorMsg("你无权访问该系统"));
		}
		// 生成token
		String token = DigestUtils.md5DigestAsHex((loginReq.getName() + System.currentTimeMillis()).getBytes());
		// 存入redis 3天有效
		redisTemplate.opsForValue().set(String.format(TOKEN_PREFIX, one.getId()), token, 3, TimeUnit.DAYS);
		return getUserVOResponseBean(one, token);
	}

	private ResponseBean<UserVO> getUserVOResponseBean(User one, String token) {
		UserVO userVO = BeanUtil.copyProperties(one, UserVO.class);
		userVO.setToken(token);
		if (one.getActiveFamilyId() != null && one.getActiveFamilyId() > 0) {
			FamilyMember familyMember = familyMemberService.lambdaQuery().eq(FamilyMember::getUserId, one.getId()).eq(FamilyMember::getFamilyId, one.getActiveFamilyId()).last("limit 1").one();
			if (familyMember != null) {
				userVO.setRole(familyMember.getRole());
			}
		}
		return new ResponseBean<UserVO>().success(userVO);
	}

	@ApiOperation("编辑用户信息")
	@PostMapping("/user/update")
	public ResponseBean<Boolean> userUpdate(@RequestBody @Valid AdminUserUpdateReq req) {
		log.info("编辑用户信息 req={}", JSONUtil.toJsonStr(req));
		if (StrUtil.isNotBlank(req.getRole()) || Objects.nonNull(req.getActiveFamilyId())) {
			familyMemberService.lambdaUpdate().eq(FamilyMember::getUserId, req.getId())
					.set(StrUtil.isNotBlank(req.getRole()), FamilyMember::getRole, req.getRole())
					.set(Objects.nonNull(req.getActiveFamilyId()), FamilyMember::getFamilyId, req.getActiveFamilyId())
					.update();
		}
		if (Objects.nonNull(req.getActiveFamilyId()) || StrUtil.isNotBlank(req.getName()) || StrUtil.isNotBlank(req.getPassword())) {
			String md5Password = StrUtil.isNotBlank(req.getPassword()) ? DigestUtils.md5DigestAsHex(req.getPassword().getBytes()) : "";
			userService.lambdaUpdate().eq(User::getId, req.getId())
					.set(StrUtil.isNotBlank(req.getName()), User::getName, req.getName())
					.set(StrUtil.isNotBlank(md5Password), User::getPassword, md5Password)
					.set(Objects.nonNull(req.getActiveFamilyId()), User::getActiveFamilyId, req.getActiveFamilyId())
					.update();
		}
		return new ResponseBean<Boolean>().success(true);
	}

	@ApiOperation("重置用户密码")
	@PostMapping("/user/resetPassword")
	public ResponseBean<String> resetPassword(@RequestBody @Valid AdminUserResetPwdReq req) {
		log.info("重置用户密码 req={}", JSONUtil.toJsonStr(req));
		String newPwd = "123456";
		String md5Password = DigestUtils.md5DigestAsHex(newPwd.getBytes());
		userService.lambdaUpdate().eq(User::getId, req.getId())
				.set(User::getPassword, md5Password)
				.update();
		return new ResponseBean<String>().success(newPwd);
	}

	@ApiOperation("用户创建")
	@PostMapping("/user/create")
	public ResponseBean<Long> userCrate(@RequestBody @Valid AdminUserCreateReq user) {
		// 查询用户名是否存在
		User one = userService.lambdaQuery().eq(User::getName, user.getName()).last("limit 1").one();
		if (one != null) {
			return new ResponseBean<Long>().exception(UserStatusEnum.ERROR.addErrorMsg("用户名已存在"));
		}
		User copied = BeanUtil.copyProperties(user, User.class);
		copied.setPassword(DigestUtils.md5DigestAsHex(user.getPassword().getBytes()));
		userService.save(copied);

		FamilyMember member = new FamilyMember();
		member.setFamilyId(user.getActiveFamilyId());
		member.setUserId(copied.getId());
		member.setRole(user.getRole());
		familyMemberService.save(member);

		return new ResponseBean<Long>().success(copied.getId());
	}

	@PostMapping("/adminSetPrompt")
	@ApiOperation("设置全局统一prompt")
	public ResponseBean<Boolean> adminSetPrompt(@RequestBody PromptModifyReq promptModifyReq) {
		log.info("promptModifyReq:", JSONUtil.toJsonStr(promptModifyReq));
		String reportPrompt = promptModifyReq.getReportPrompt();
		if (StringUtils.isNotBlank(reportPrompt)) {
			redisTemplate.opsForValue().set(REPORT_PROMPT_KEY, reportPrompt, 20 * 365, TimeUnit.DAYS);
		}
		String sessionPrompt = promptModifyReq.getSessionPrompt();
		if (StringUtils.isNotBlank(sessionPrompt)) {
			sessionService.lambdaUpdate().eq(Session::getRole, Role.SYSTEM.getValue()).set(Session::getContent, sessionPrompt).update();
			redisTemplate.opsForValue().set(SESSION_PROMPT_KEY, sessionPrompt, 20 * 365, TimeUnit.DAYS);
		}
		return new ResponseBean<Boolean>().success(true);
	}

	@GetMapping("/adminGetPrompt")
	@ApiOperation("获取全局统一prompt")
	public ResponseBean<AdminPromptResp> adminSetPrompt() {
		String propertyPrompt = redisTemplate.opsForValue().get(REPORT_PROMPT_KEY);
		String sessionPrompt = redisTemplate.opsForValue().get(SESSION_PROMPT_KEY);
		AdminPromptResp promptResp = AdminPromptResp.builder()
				.reportPrompt(Objects.isNull(propertyPrompt) ? new GenerateReportReq().getReportPrompt() : propertyPrompt)
				.reportPromptSuffix(SESSION_PROMPT_SUFFIX)
				.sessionPrompt(Objects.isNull(sessionPrompt) ? new CreateUserSession().getContent() : sessionPrompt)
				.build();
		return new ResponseBean<AdminPromptResp>().success(promptResp);
	}
}

